/*
This software has been developed by Ralph M. Butler for the 
sole use of his students.  No one else may copy any part 
of it for any reason, except with explicit permission.
*/

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include <varargs.h>

caddr_t create_shmem();

int myid;
int pagesize;

main(argc,argv)
int argc;
char **argv;
{
    int i, j, rc;
    char *sp;
    msemaphore *msemp;

    pagesize = getpagesize();
    myid = 0;
    sp = (char *) create_shmem(pagesize);
    msemp = msem_init(sp+0,MSEM_UNLOCKED);
    if (msemp == (msemaphore *) NULL)
    {
	dprintf("msem_init failed: msemp=%d  errno=%d  %s\n",msemp,errno,sys_errlist[errno]);
	exit(99);
    }
    rc = msem_lock(msemp,0);
    if (rc < 0)
    {
	dprintf("msem_lock failed: rc=%d  errno=%d  %s\n",rc,errno,sys_errlist[errno]);
	exit(99);
    }

    for (i=1; i < 2; i++)
    {
	rc = fork();
	if (rc < 0)
	{
	    dprintf("fork failed \n");
	    exit(99);
	}
	if (rc == 0)
	{
	    myid = i;
	    /*****/
	    rc = msem_lock(msemp,0);
	    if (rc < 0)
	    {
		dprintf("msem_lock failed in subprocess: rc=%d  errno=%d  %s\n",rc,errno,sys_errlist[errno]);
		exit(99);
	    }
	    /*****/
	    dprintf("spval=%c\n",(char) sp[8191]);
	    rc = msem_unlock(msemp,0);
	    exit(0);
	}
    }
    for (i=1000; i < pagesize; i++)  /* skip semaphores and pad */
    {
	sp[i] = 'R';
    }
    rc = msem_unlock(msemp,0);
    sleep(2);  /* give child a chance */
    if (rc < 0)
    {
	dprintf("msem_lock failed in subprocess: rc=%d  errno=%d  %s\n",rc,errno,sys_errlist[errno]);
	exit(99);
    }
    rc = msem_lock(msemp,0);
}

caddr_t create_shmem(nbytes)
int nbytes;
{
    int i,mmfd;
    caddr_t mmp, shmem;

    shmem = (caddr_t) malloc(2*pagesize);
    mmp = mmap(shmem,nbytes,PROT_READ|PROT_WRITE|PROT_EXEC,
	       MAP_ANONYMOUS|MAP_SHARED|MAP_VARIABLE,-1,0);
    if (mmp == (caddr_t) -1)
    {
	dprintf("mmap failed: mmp=%d  errno=%d  %s\n",mmp,errno,sys_errlist[errno]);
	exit(99);
    }
    dprintf("shmem=%x mmp=%x \n",shmem,mmp);
    return(mmp);
}

dprintf(fmt, va_alist)
char *fmt;
va_dcl
{
    va_list ap;

    printf("%d: ",myid);
    va_start(ap);
    vprintf(fmt, ap);
    va_end(ap);
    fflush(stdout);
}
